<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title></title>
</head>
<body>
	<script type="text/javascript">
	// var object = {};
	// object[1] = 1;

	// function foo(){

	// }

	// foo.prototype.z = 3;
	// var obj = new foo();
	// console.log(obj.__proto__.__proto__.__proto__);
	// console.log(foo.prototype.constructor);

	// obj.x = 10;
	// obj.y = 20;
	// console.log("z" in obj);   //检测当前对象有没有某属性
	// console.log(obj.x + "," + obj.y + ","+ obj.z);
	// console.log(foo.prototype.hasOwnProperty("z"));   //hasOwnProperty（attr）判断当前对象有没有某属性


	// ECMA5  Object.create()创建对象，参数是对象类型，通过Object.create()创建的对象的原型链指向通过参数传递进来的对象
	// var box = {name:"xiaohei0",age:18}
	// var obj = Object.create(box);
	// console.log(obj);


	function foo(){}
	foo.prototype.z = 3;

	var obj =new foo();
	obj.y = 2;
	obj.x = 1;

	obj.x;		 // 1
	obj.y; 		// 2
	obj.z;		 // 3
	typeof obj.toString;     		  // function
	console.log('z' in obj);            		  	//检测当前对象有没有某属性 输出：true
	console.log(obj.hasOwnProperty('z'));		 //hasOwnProperty（attr）判断当前对象有没有某属性 输出：false


	obj.z = 5;
	console.log(obj.hasOwnProperty('z')); // true
	foo.prototype.z; // still 3
	obj.z; // 5

	obj.z = undefined;
	obj.z; // undefined

	delete obj.z; // true
	obj.z; // 3

	delete obj.z; // true
	obj.z; // still 3!!!




	// 获取对象指定属性的标签对象
	// 属性删除
	var person = {age:28,title:"nihao"};
	delete person.age;     //true
	delete person["title"];   //true
	console.log(delete person["title"] )
	person.age;    //undefined
	console.log(person.age);
	delete Object.prototype;   //false
	console.log(delete Object.prototype);
	var descriptor = Object.getOwnPropertyDescriptor(Object,"prototype");  //getOwnPropertyDescriptor:获取对象指定属性的标签对象,标签对象下有如下几个重要的属性
	// configurable：false   是否可操作
	// enumerable:false  是否枚举      可枚举的能被for(in)遍历出来，不能枚举的不能遍历出来
	// value： object 属性值
	// writable:  false是否可写
	// 
	console.log(descriptor);
	// 因为configurable为false；所以Object.prototype不能删除






	// 函数的自我调用
	// (function(){
	// 	alert(“100”);
	// // })();
	// 
	// 在全局作用域下、或者函数内部作用域下，delete 都返回false，删除失败
	// 包括全局作用域下函数的删除也是不行的，但是通过window.创建的是可以被删除的 
	
	
	



	// 属性检测
	var cat = new Object();
	cat.legs=4;
	cat.age=4;
	console.log(cat.propertyIsEnumerable("legs"));
	console.log(cat.propertyIsEnumerable("toString"));
	// 检测对象是否可枚举
	// 通过“ . ”来创建的属性都返回true 
	// 
	// 给对象创造属性
	// Object.defineProperty()
	//第一个参数：当前对象
	//第二个参数：要创建的属性名称
	//第三个参数：字面量的Object对象
	var cat = new Object();
		cat.age=4;
	Object.defineProperty(cat,  "name",{
		enumerable:false,    //设置不可枚举
		value:"哆啦A梦"
	});
	console.log(cat.name);    //此处应该 .name  ,因为value给的是属性值，name才是属性
	for(attr in cat){		
		console.log(attr);    //只输出age
	}
	// ps:只要还通过Object.defineProperty创建的属性，name该属性的属性标签默认都为false
	console.log( Object.getOwnPropertyDescriptor(cat,"name"));  //返回一个对象
	//注意：多个添加，要把"y"改成ies  Object.defineProperties(当前对象，{属性名称：{标签对象}})
	Object.defineProperties(cat, {          
		"name":{value:"哆啦A梦"},
		"home":{value:18,enumerable:true}
	});
	for(attr in cat){		
		console.log(attr);   //age home
	}




	// 属性枚举
	var o = {x:1,y:2,z:3};
	console.log("toString" in o);//true
	console.log(o.propertyIsEnumerable("toString"));    //检测对象是否可枚举,false
	var key;
	for(key in o){
		console.log(key);    //x,y,z
	}

	var obj = Object.create(o);
	obj.a=4;
	var key;
	for(key in obj){
		console.log(key);  //a,x,y,z
	}


	var obj = Object.create(o);
	obj.a=4;
	var key;
	for(key in obj){
		if(obj.hasOwnProperty(key)){
		console.log(key);    //a
		}
	}





	// 另一种读写的方式getter/setter
	var man = {
		name:"xiaohei",
		grade :18,
		get age(){
			return new Date().getFullYear()-2000;
		},
		set age(val){
			console.log("今年我才" + val);
		}
	}
	console.log(man.age);   //17
	man.age = 5;   //今年我才5,相当于调用了函数,(即赋值的时候间接调用了函数)
	console.log(man.age);   //17


	//set设置属性值，get得到属性值
	var man = {
		myName:"xiaohei",       //实际的属性
		grade :18,
		get name(){     //name操作的属性名
			return this.myName;
		},
		set name(val){
			this.myName = val;
			// console.log("我的名字是" + val);
		}
	}
	console.log(man.name);   //xiaohei
	man.name = "大白";   
	console.log(man.name);   //大白


	//get 、set与原型链
	function Foo(){}
	var obj = new Foo();    //创建对象
	// 通过Object.defineProperty给Foo.prototype（原型）添加属性
	Object.defineProperty(obj,"z",{
		configurable:true,writable:true,value:70
	})
	console.log(obj.z);     //80   
	obj.z=80;
	console.log(obj.z);   //80,writable:true必须设置，否则输出为70（返回的对象不能修改它的值）
	console.log(obj.hasOwnProperty("z"));    //true


	function Person(){}
	Person.prototype.y=100;
	var obj = new Person();
	obj.name = "xiaohei";
	Object.defineProperty(obj,"type",{
		configurable:true,
		writable:true,
		enumerable:false,
		value:"Object"
	})
	console.log(Person.prototype.propertyIsEnumerable("y"));
	console.log(Object.keys(obj));   //获取当前对象下课枚举的属性或行为，不会去原型链上去找
	//返回的是一个结果数组
	
	
	
	
	
	
	


	
	// 对象标签
	// proto\class\extensible
	var toString = Object.prototype.toString;
	function getClass(obj){//通过call或者apply实现对象冒充（改变函数的一个执行对象）

		return  toString.call(obj).slice(8,-1);   //返回处理过的构造函数的名称
	}

	console.log(getClass(null));			//Null
	console.log(getClass(undefined));		//Undefined
	console.log(getClass(11));    			//Number
	console.log(getClass(new Number()));    //Number
	console.log(getClass(new Boolean()));   //Boolean
	console.log(getClass("nihap")); 		//String
	console.log(getClass(true)); 		    //Boolean


	// //判断该对象是否能够修改现有属性，是否能添加新属性，不能的话返回true，否则返回false
	// Object.isSealed(object);
	
	// //判断该对象是否能够修改现有属性和值，是否能添加新属性，不能的话返回true，否则返回false
	// Object.isFrozen(object);

	// // 判断该对象是否可向对象添加新属性,可以则返回false,被冻结则返回true
	// Object.isExtensible(object);

	// // 返回属于自己的属性和行为
	// Object.getOwnPropertyNames(object);


	var obj = new Object();
	obj.name = "xiaohei";
	// // Object.freeze(obj);      //此时返回true、true、false；若此句不加则返回false、false、true
	// Object.seal(obj);          //此时返回true、false、false、
	Object.preventExtensions(obj);  //此时返回false、false、false
	console.log("isSealed:" + Object.isSealed(obj));
	console.log("isFrozen:" + Object.isFrozen(obj));
	console.log("isExtensible:" + Object.isExtensible(obj));
	



	// 阻止修改现有属性的特性和值，并阻止添加新属性  Object.freeze()   冻结对象
	var obj = new Object();
	obj.name = "xiaohei";
	obj.age = 18;
	// 进行阻止
	Object.freeze(obj);       //该句存在时，console.log输出undefined，否则输出“女”
	// 下面添加新属性无效
	obj.sex = "女";
	console.log(obj.sex);
	Object.defineProperty(obj,"age",{writable:false});
	obj.age = 28;
	// 下面修改属性无效
	console.log(obj.age);    //输出18




	//阻止向对象添加新属性Object.preventExtensions(object)   阻止扩展
	var obj = new Object();
	obj.name = "xiaohei";
	obj.age = 18;
	// Object.preventExtensions(obj);
	Object.defineProperty(obj,"sex",{value:"男"});
	obj.age = 100;
	console.log(obj.age);
	console.log(obj.sex);





	// 阻止修改现有属性的特性，并阻止添加新属性Object.seal()  密封
	var obj = new Object();
	obj.name = "xiaohei";
	obj.age = 18;
	Object.seal(obj);
	obj.age=25;
	obj.sex="女";
	// obj = {
	// 	sex:"女"
	// }
	console.log(obj.age);
	console.log(obj.sex);




	// JSON   序列化、反序列化    原生的js对象
	// 
	// 序列化：把json对象转化为字符串
	// 反序列化：把json字符串转化为对象
	var goods = {
		'fruit':[
			{
				name:"凤梨",
				price:6.6,
				brand:"老板牌"
			},
			{
				name:"凤梨",
				price:6.6,
				brand:"老板牌"
			},
			{
				name:"凤梨",
				price:6.6,
				brand:"老板牌"
			}
		],
		date:new Date()
	}
	// 序列化
	var result = JSON.stringify(goods);    //JSON字符串
	console.log(result);
	//输出：{"fruit":[{"name":"凤梨","price":6.6,"brand":"老板牌"},{"name":"凤梨","price":6.6,"brand":"老板牌"},{"name":"凤梨","price":6.6,"brand":"老板牌"}],"date":"2017-03-23T08:36:33.543Z"}
	console.log(typeof result);   //string
	// 反序列化
	console.log(JSON.parse(result));
	console.log(goods.fruit[0]); 
	console.log(goods.fruit[0].price);   //6.6


	function foo(){}
		foo.prototype.z = 3;

		var obj =new foo();
		obj.y = 2;
		obj.x = 1;

		obj.x; // 1
		obj.y; // 2
		obj.z; // 3
		console.log(typeof obj.toString); // ‘function'
		'z' in obj; // true
		obj.hasOwnProperty('z'); // false

// 	var weather ={
//     "HeWeather5":[
//         {
//             "basic": {
//                 "city": "北京",
//                 "cnty": "中国",
//                 "id": "CN101010100",
//                 "lat": "39.904000",
//                 "lon": "116.391000",
//                 "update": {
//                     "loc": "2017-03-23 16:02",
//                     "utc": "2017-03-23 08:02"
//                 }
//             },
//             "daily_forecast": [
//                 {
//                     "astro": {
//                         "mr": "03:07",
//                         "ms": "13:23",
//                         "sr": "06:13",
//                         "ss": "18:29"
//                     },
//                     "cond": {
//                         "code_d": "305",
//                         "code_n": "305",
//                         "txt_d": "小雨",
//                         "txt_n": "小雨"
//                     },
//                     "date": "2017-03-23",
//                     "hum": "58",
//                     "pcpn": "5.8",
//                     "pop": "100",
//                     "pres": "1024",
//                     "tmp": {
//                         "max": "10",
//                         "min": "2"
//                     },
//                     "uv": "2",
//                     "vis": "13",
//                     "wind": {
//                         "deg": "125",
//                         "dir": "东风",
//                         "sc": "微风",
//                         "spd": "3"
//                     }
//                 },
//                 {
//                     "astro": {
//                         "mr": "03:49",
//                         "ms": "14:22",
//                         "sr": "06:11",
//                         "ss": "18:30"
//                     },
//                     "cond": {
//                         "code_d": "305",
//                         "code_n": "104",
//                         "txt_d": "小雨",
//                         "txt_n": "阴"
//                     },
//                     "date": "2017-03-24",
//                     "hum": "68",
//                     "pcpn": "3.3",
//                     "pop": "100",
//                     "pres": "1022",
//                     "tmp": {
//                         "max": "7",
//                         "min": "0"
//                     },
//                     "uv": "2",
//                     "vis": "14",
//                     "wind": {
//                         "deg": "43",
//                         "dir": "南风",
//                         "sc": "微风",
//                         "spd": "3"
//                     }
//                 },
//                 {
//                     "astro": {
//                         "mr": "04:28",
//                         "ms": "15:25",
//                         "sr": "06:10",
//                         "ss": "18:31"
//                     },
//                     "cond": {
//                         "code_d": "101",
//                         "code_n": "100",
//                         "txt_d": "多云",
//                         "txt_n": "晴"
//                     },
//                     "date": "2017-03-25",
//                     "hum": "54",
//                     "pcpn": "0.0",
//                     "pop": "10",
//                     "pres": "1022",
//                     "tmp": {
//                         "max": "14",
//                         "min": "4"
//                     },
//                     "uv": "4",
//                     "vis": "18",
//                     "wind": {
//                         "deg": "246",
//                         "dir": "南风",
//                         "sc": "微风",
//                         "spd": "0"
//                     }
//                 }
//             ],
//             "status": "ok"
//         }
//     ]
// }

// 	console.log("城市:"+weather.HeWeather5[0].basic.city+",天气:" + weather.HeWeather5[0].daily_forecast[0].cond.txt_d + ",日期：" + weather.HeWeather5[0].daily_forecast[0].date);
	
	</script>
</body>
</html>